/**
 * 学生服务模块
 */

const { addStudents, updateStudents, changeStatus, searchStudents, existsByIdNo, getStudentStatus, changeRecord, addEmergencyContact, updateEmergencyContact, deleteEmergencyContact, getEmergencyContacts, searchStudentsArchives, searchFee, addFee } = require('../db/students');
const { existsById } = require('../db/class_list');
const { getClassName } = require('../db/class_list');
const fs = require('fs');
const path = require('path');
const { avatar } = require('../config.json');

/**
 * 保存文件
 * @param {*} file 要保存的文件
 */
const saveFile = (file, student) => {
    const { filepath, newFilename, originalFilename } = file;
    const folder = path.resolve(__dirname, '../static/', avatar);  //头像保存文件夹
    if (!fs.existsSync(folder)) {
        fs.mkdirSync(folder);
    }
    const read = fs.createReadStream(filepath); //创建读取流，读取上传的临时文件
    const ext = '.' + originalFilename.split('.').pop();
    const write = fs.createWriteStream(path.join(folder, newFilename + ext));   //创建写入流
    read.pipe(write);
    write.on('close', () => {
        read.destroy();
        write.destroy();
    });
    student.avatar = path.join('/' + avatar, newFilename + ext);
}

/**
 * 添加学生
 * @param {*} ctx 
 */
const add = async ctx => {
    try {
        const student = ctx.request.body;
        const file = ctx.request.files?.file;
        const { mimetype } = (file || {});
        if (file && !/^image\/.+/.test(mimetype)) {
            return ctx.body = {
                code: 0,
                msg: '头像请勿上传非图片文件'
            }
        }
        const classInfo = await existsById(student.class_id);
        if (!classInfo) {
            return ctx.body = {
                code: 0,
                msg: '班级不存在，请勿非法操作'
            }
        }
        const { idNo } = student;
        const info = await existsByIdNo(0, idNo);
        if (info) {
            return ctx.body = {
                code: 0,
                msg: '已存在相同的身份证号'
            }
        }
        const { record, oldSchool } = student;
        delete student.record;
        delete student.oldSchool;
        file && saveFile(file, student);
        await addStudents(student, { record, oldSchool });
        ctx.body = {
            code: 1,
            msg: '学生添加成功'
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '学生添加失败'
        }
    }
}

/**
 * 修改学生
 * @param {*} ctx 
 * @returns 
 */
const update = async ctx => {
    try {
        const student = ctx.request.body;
        const { id, idNo } = student;
        delete student.id;
        const file = ctx.request.files?.file;
        const { mimetype } = (file || {});
        if (file && !/^image\/.+/.test(mimetype)) {
            return ctx.body = {
                code: 0,
                msg: '头像请勿上传非图片文件'
            }
        }
        const info = await existsByIdNo(id, idNo);
        if (info) {
            return ctx.body = {
                code: 0,
                msg: '已存在相同的身份证号'
            }
        }
        file && saveFile(file, student);
        await updateStudents(id, student);
        ctx.body = {
            code: 1,
            msg: '学生修改成功'
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '学生修改失败'
        }
    }
}

/**
 * 更改状态
 * @param {*} ctx 
 */
const change = async ctx => {
    try {
        const { id, status } = ctx.request.body;
        await changeStatus(id, status);
        ctx.body = {
            code: 1,
            msg: '学生状态更改成功'
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '学生状态更改失败'
        }
    }
}

/**
 * 更改状态
 * @param {*} ctx 
 */
const search = async ctx => {
    try {
        const [data, total] = await searchStudents(ctx.request.query);
        ctx.body = {
            code: 1,
            data,
            total
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '学生列表搜索失败'
        }
    }
}

/**
 * 更改档案
 * @param {*} ctx 
 */
const updateRecord = async ctx => {
    try {
        const { body } = ctx.request;
        const { id, record, class_id: cid } = body;
        delete body.id;
        const obj = await getStudentStatus(id);
        if (!obj) {
            return ctx.body = {
                code: 0,
                msg: '学生信息不存在，请勿非法操作'
            }
        }
        const { status, class_id } = obj;
        switch (record) {
            case 21:
                if (status !== 26) {
                    return ctx.body = {
                        code: 0,
                        msg: '此学生非转出状态，请勿非法操作'
                    }
                }
                break;
            case 22:
                if (status !== 23 && status !== 24) {
                    return ctx.body = {
                        code: 0,
                        msg: '此学生非正常或休学状态，不能调班'
                    }
                }
                break;
            case 27:
                if (status !== 23 && status !== 24) {
                    return ctx.body = {
                        code: 0,
                        msg: '此学生非正常或休学状态，不能转出'
                    }
                }
                break;
            case 28:
                if (status !== 23 && status !== 24) {
                    return ctx.body = {
                        code: 0,
                        msg: '此学生非正常或休学状态，不能毕业'
                    }
                }
                break;
        }
        if (cid === class_id) {
            return ctx.body = {
                code: 0,
                msg: '请勿调至原班级'
            }
        }
        let class_name, old_class_name;
        if (record === 21) {
            const [classInfo] = await getClassName(cid);
            if (!classInfo) {
                return ctx.body = {
                    code: 0,
                    msg: '转入的班级不存在，请勿非法操作'
                }
            }
            class_name = classInfo.name;
        }
        else if (record === 22) {
            //调班则判断新旧班级是否都存在
            const classInfos = await getClassName([class_id, cid]);
            if (classInfos.length !== 2) {
                return ctx.body = {
                    code: 0,
                    msg: '新旧班级其中一个不存在，请勿非法操作'
                }
            }
            class_name = classInfos.find(c => c.id === cid).name;
            old_class_name = classInfos.find(c => c.id === class_id).name;
        }
        await changeRecord(id, { ...body, class_id: cid, old_class_id: class_id, class_name, old_className: old_class_name });
        ctx.body = {
            code: 1,
            msg: '学生档案更改成功'
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '学生档案更改失败'
        }
    }
}


/**
 * 添加紧急联系人
 * @param {*} ctx 
 */
const addEmergency = async ctx => {
    try {
        await addEmergencyContact(ctx.request.body);
        ctx.body = {
            code: 1,
            msg: '学生紧急联系人添加成功'
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '学生紧急联系人添加失败'
        }
    }
}

/**
 * 修改紧急联系人
 * @param {*} ctx 
 */
const updateEmergency = async ctx => {
    try {
        const obj = ctx.request.body;
        const id = obj.id;
        delete obj.id;
        await updateEmergencyContact(id, obj);
        ctx.body = {
            code: 1,
            msg: '学生紧急联系人修改成功'
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '学生紧急联系人修改失败'
        }
    }
}

/**
 * 添加紧急联系人
 * @param {*} ctx 
 */
const deleteEmergency = async ctx => {
    try {
        await deleteEmergencyContact(ctx.request.params.id);
        ctx.body = {
            code: 1,
            msg: '学生紧急联系人删除成功'
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '学生紧急联系人删除失败'
        }
    }
}

/**
 * 获取紧急联系人列表
 * @param {*} ctx 
 */
const getEmergencyList = async ctx => {
    try {
        const data = await getEmergencyContacts(ctx.request.params.id);
        ctx.body = {
            code: 1,
            data
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '学生紧急联系人获取失败'
        }
    }
}

/**
 * 搜索学生档案
 * @param {*} ctx 
 */
const searchArchives = async ctx => {
    try {
        const [data, total] = await searchStudentsArchives(ctx.request.query);
        ctx.body = {
            code: 1,
            data,
            total
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '学生档案搜索失败'
        }
    }
}

/**
 * 添加学生费用
 * @param {*} ctx 
 */
const addStudentFee = async ctx => {
    try {
        await addFee(ctx.request.body);
        ctx.body = {
            code: 1,
            msg: '学生费用添加成功'
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '学生费用添加失败'
        }
    }
}

/**
 * 搜索学生费用
 * @param {*} ctx 
 */
const searchStudentFee = async ctx => {
    try {
        const [data, total] = await searchFee(ctx.request.query);
        ctx.body = {
            code: 1,
            data,
            total
        }
    } catch (error) {
        ctx.app.emit('error', error);
        ctx.body = {
            code: 0,
            msg: '学生费用搜索失败'
        }
    }
}

module.exports = {
    add,
    update,
    change,
    search,
    updateRecord,
    addEmergency,
    addStudentFee,
    searchArchives,
    updateEmergency,
    deleteEmergency,
    getEmergencyList,
    searchStudentFee,
}